package com.atguigu.springcloud.config;

import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer;
import com.atguigu.springcloud.cache.GosuncnCacheHandler;
import com.atguigu.springcloud.common.ThreadLocalProxyHolder;
import com.atguigu.springcloud.extend.ICacheHashOneDay;
import com.atguigu.springcloud.extend.RedisLock;
import com.atguigu.springcloud.extend.RedisService;
import com.atguigu.springcloud.extend.StringRedisTemplate;
import com.atguigu.springcloud.extend.impl.CacheHashOneDay;
import com.atguigu.springcloud.extend.impl.DefaultRedisServiceImpl;
import com.atguigu.springcloud.extend.impl.RedisDistributedLock;
import com.atguigu.springcloud.user.ISystemUser;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration
public class StarterConfiguration {


    /**
     * 我们自定义一个 RedisTemplate，设置序列化器，这样我们可以很方便的操作实例对象。
     * 否则redis自动使用对象的jdk序列化 获取不到 key value
     */
    @Bean
    public StringRedisTemplate redisTemplate(RedisConnectionFactory factory) {


        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(factory);
        //为了自己开发开发方便，一般直接使用<String, Serializable> 类型
//        RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>();
        //value序列化
//        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        //key序列化方式
        template.setKeySerializer(stringRedisSerializer);
        //key序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
        template.setValueSerializer(fastJsonRedisSerializer);
        template.setHashValueSerializer(fastJsonRedisSerializer);
        template.afterPropertiesSet();

        return template;
    }


    //redis方法封装类注入bean
    @Bean
    @ConditionalOnMissingBean
    public RedisService redisService() {
        DefaultRedisServiceImpl service = new DefaultRedisServiceImpl();
        return service;
    }

    //redis方法封装类注入bean
    @Bean
    @ConditionalOnMissingBean
    public RedisLock redisLock() {
        RedisDistributedLock redisLock = new RedisDistributedLock();
        return redisLock;
    }

    @Bean
    @ConditionalOnMissingBean
    public ICacheHashOneDay cacheHashOneDay(RedisService redisService) {
        return new CacheHashOneDay(redisService);
    }

    //用于定义了@GosunCache注解，进行AOP切面标识
    @Bean
    @ConditionalOnProperty(name = "gosuncn.cache.enable", havingValue = "true", matchIfMissing = true)
    public GosuncnCacheHandler gosuncnCacheHandler(RedisService redisService) {
        return new GosuncnCacheHandler(redisService);
    }


    //注册代理对象实例
    @Bean
    @ConditionalOnMissingBean
    public ISystemUser iSystemUser() {
        return ThreadLocalProxyHolder.getContextHolderProxy(ISystemUser.class);
    }


}
